package com.dks.repository.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dks.dto.DoctorWebDto;
import com.dks.mapper.RecordDateMapper;
import com.dks.mapper.TalksRecordMapper;
import com.dks.models.RecordDate;
import com.dks.models.TalksRecord;
import com.dks.repository.ITalksRecordRepository;
import com.dks.result.ResultModel;
import com.dks.util.Commond;
import com.dks.util.PageInfo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sun.jndi.toolkit.url.UrlUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.dks.util.Commond.MSG_SUCCESS;
import static com.dks.util.Commond.R_SUCCESS;

@Repository
public class TalksRecordRepository implements ITalksRecordRepository {

    @Resource
    private TalksRecordMapper talksRecordMapper;

    @Resource
    private RecordDateMapper recordDateMapper;

    /**
     * 手机号脱敏筛选正则
     */
    public static final String PHONE_BLUR_REGEX = "(\\d{3})\\d{4}(\\d{4})";

    /**
     * 手机号脱敏替换正则
     */
    public static final String PHONE_BLUR_REPLACE_REGEX = "$1****$2";


    @Override
    public ResultModel<Boolean> insert(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();

        if(StringUtils.isEmpty(talksRecord.getRecordCertificateNumber())){
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("备案号不可以为空");
            resultModel.setData(talksRecord);
            return resultModel;
        }

        //判断人数
        //查找当前时间预约公司数
        Map map1 = new HashMap();
        map1.put("recordTimeLike", talksRecord.getRecordTime());
        List<TalksRecord> talksRecords1 = talksRecordMapper.selectList(map1);
        //总公司数加上自己对应的总数
        int peoplecounts = talksRecords1.size() + 1;

        //查找当前时间医生设置的人数，如果没有设置默认为20
        Map map2 = new HashMap();
        map2.put("recordTime", talksRecord.getRecordTime());
        List<RecordDate> recordDateList = recordDateMapper.getByMapList(map2);

        int recordCounts = recordDateList.size() == 0 ? 20 : recordDateList.size();

        //当前预约公司数比当天设置公司数多不可以预约
        if (peoplecounts > recordCounts) {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("当前时间预约人数已满,请选择其他时间");
            resultModel.setData(0);
            return resultModel;
        }

        //限制一个人一天只能预约三次
        Map<String, Object> map = new HashMap<>();
        map.put("tel", talksRecord.getTel());

        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateNowStr = sdf.format(d);
        map.put("createTime", dateNowStr + " 00:00:00");
        List<TalksRecord> talksRecords = talksRecordMapper.selectList(map);

        if (CollectionUtils.isNotEmpty(talksRecords)) {
            if (talksRecords.size() == 3) {
                resultModel.setCode(Commond.CODE_FAIL);
                resultModel.setMessage("每人每天只能预约三次");
                resultModel.setData(0);
                return resultModel;
            } else if (talksRecords.get(0).getRecordStatus() == 1 || talksRecords.get(0).getRecordStatus() == 2 || talksRecords.get(0).getRecordStatus() == 5) {
                resultModel.setCode(Commond.CODE_FAIL);
                resultModel.setMessage("您已在排队列表中，请勿重复预约");
                resultModel.setData(0);
                return resultModel;
            }
        }

        int row = talksRecordMapper.insert(talksRecord);
        if (1 == row) {
            resultModel.setCode(Commond.CODE_SUCCESS);
            resultModel.setMessage(MSG_SUCCESS);
            resultModel.setData(row);
        } else {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage(Commond.MSG_FALE);
            resultModel.setData(row);
        }
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> update(TalksRecord talksRecord) {
        int row = talksRecordMapper.update(talksRecord);
        ResultModel resultModel = new ResultModel();
        if (1 == row) {
            resultModel.setCode(Commond.CODE_SUCCESS);
            resultModel.setMessage(MSG_SUCCESS);
            resultModel.setData(row);
        } else {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage(Commond.MSG_FALE);
            resultModel.setData(row);
        }
        return resultModel;
    }

    @Override
    public ResultModel selectById(Integer id) {
        ResultModel resultModel = new ResultModel();
        TalksRecord talksRecord = talksRecordMapper.selectById(id);
        resultModel.setCode(Commond.CODE_SUCCESS);
        resultModel.setMessage(MSG_SUCCESS);
        resultModel.setData(talksRecord);

        return resultModel;
    }

    @Override
    public ResultModel<PageInfo<TalksRecord>> selectList(Integer pageNum, Integer pageSize, String beginTime, Integer departmentId) {
        ResultModel resultModel = new ResultModel();

        // 判断当前日期往后的日期中是否有医生临时有事取消预约的记录，如果有直接返回相关信息
        Map map1 = new HashMap();
        map1.put("recordTimeParam", beginTime);
        List<RecordDate> recordDateList = recordDateMapper.getByMapList(map1);
        //过滤出不可用的
        recordDateList = recordDateList
                .stream()
                .filter(recordDate -> null != recordDate && recordDate.getRecStatus() == 1)
                .sorted(Comparator.comparing(RecordDate::getRecordTime).reversed())
                .collect(Collectors.toList());


        if (CollectionUtils.isNotEmpty(recordDateList)) {

            // 如果有值判断当前排队时间和预约时间第一条是不是一天如果是一天则结束返回相关提示
            RecordDate recordDate = recordDateList.get(0);

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            //返回时间 yy-mm-dd
            String returnTime = null;
            SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");

            Date beginTime1 = null;

            try {
                beginTime1 = dateFormat.parse(beginTime);
                returnTime = dateFormat1.format(recordDate.getRecordTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }

            //判断时间是同一天
            if (DateUtils.isSameDay(beginTime1, recordDate.getRecordTime())) {
                resultModel.setCode(Commond.CODE_SUCCESS);
                resultModel.setMessage("因医生" + returnTime + "临时有事,预约取消");
                resultModel.setData(null);
                return resultModel;
            }

        }
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", beginTime);
        // 排除医生或客户已结束的
        map.put("recordListStatus", 3);
        // 排除客户主动取消预约的
        map.put("endRecordListStatus", 4);
        // 根据科室选择
        map.put("departmentId", departmentId);
        //进行中的在前,未开始的按照时间降序
        map.put("sortColumns", "create_time ASC");
        Page p = PageHelper.startPage(pageNum, pageSize);
        List<TalksRecord> talksRecords = talksRecordMapper.selectList(map);
        //手机号脱敏处理
        List<TalksRecord> talksRecordRes = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < talksRecords.size(); i++) {
            TalksRecord talksRecord = talksRecords.get(i);
            talksRecord.setTelReal(talksRecord.getTel());
            talksRecord.setTel(talksRecord.getTel().replaceAll(PHONE_BLUR_REGEX, PHONE_BLUR_REPLACE_REGEX));

            sb.delete(0, sb.length());

            if (i == 0) {
                sb.append("您目前处于队列中第一位,请进入会谈");
                talksRecord.setHintMessage(sb.toString());
            } else if (i == 1) {
                sb.append("您目前处于第二位,请到排队区等候");
                talksRecord.setHintMessage(sb.toString());
            } else {
                sb.append("当前队列中共").append(talksRecords.size()).append("人,您处于第").append(i + 1).append("位,请耐心等候");
                talksRecord.setHintMessage(sb.toString());

            }
            talksRecordRes.add(talksRecord);
        }
        PageInfo<TalksRecord> pageInfo = new PageInfo<>(pageNum, pageSize, p.getTotal(), p.getPages(), talksRecordRes);
        resultModel.setCode(Commond.CODE_SUCCESS);
        resultModel.setMessage(R_SUCCESS);
        resultModel.setData(pageInfo);
        return resultModel;
    }


    @Override
    public ResultModel<Boolean> delete(TalksRecord talksRecord) {
        talksRecord.setRecStatus(1);
        int row = talksRecordMapper.update(talksRecord);
        ResultModel resultModel = new ResultModel();
        if (1 == row) {
            resultModel.setCode(Commond.CODE_SUCCESS);
            resultModel.setMessage(MSG_SUCCESS);
            resultModel.setData(row);
        } else {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage(Commond.MSG_FALE);
            resultModel.setData(row);
        }
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> begin(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();

        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", talksRecord.getBeginTime());
        // 排除已结束的
        map.put("recordListStatus", 3);
        // 排除客户自己取消的
        map.put("recordListCancleStatus", 4);
        //进行中的在前,未开始的按照时间降序
        map.put("sortColumns", "record_status DESC , create_time ASC");
        List<TalksRecord> talksRecords = talksRecordMapper.selectList(map);

        if (CollectionUtils.isNotEmpty(talksRecords)) {
            //判断是否是第一条,如果是可以开始否则不能开始
            if (talksRecords.get(0).getId() == talksRecord.getId()) {
                talksRecord.setRecordStatus(2);
                int row = talksRecordMapper.update(talksRecord);
                resultModel.setCode(Commond.CODE_SUCCESS);
                resultModel.setMessage(MSG_SUCCESS);
                resultModel.setData(row);
            } else {
                resultModel.setCode(Commond.CODE_FAIL);
                resultModel.setMessage("请按顺序执行");
                resultModel.setData(0);
            }
            ;
        }
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> beginWaitRecord(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();

        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", talksRecord.getBeginTime());
        // 排除已结束的
        map.put("recordListStatus", 3);
        // 排除客户自己取消的
        map.put("recordListCancleStatus", 4);
        //进行中的在前,未开始的按照时间降序
        map.put("sortColumns", "record_status DESC , create_time ASC");
        List<TalksRecord> talksRecords = talksRecordMapper.selectList(map);

        if (CollectionUtils.isNotEmpty(talksRecords)) {
            //判断是否是第一条,如果是可以开始否则不能开始
            if (talksRecords.get(1).getId() == talksRecord.getId() || talksRecords.get(2).getId() == talksRecord.getId() || talksRecords.get(3).getId() == talksRecord.getId()) {
                talksRecord.setRecordStatus(5);
                int row = talksRecordMapper.update(talksRecord);
                resultModel.setCode(Commond.CODE_SUCCESS);
                resultModel.setMessage(MSG_SUCCESS);
                resultModel.setData(row);
            } else {
                resultModel.setCode(Commond.CODE_FAIL);
                resultModel.setMessage("请按顺序执行");
                resultModel.setData(0);
            }
            ;
        }
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> cancelWaitRecord(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();
        TalksRecord talksRecord1 = talksRecordMapper.selectById((int) (talksRecord.getId()));
        if (talksRecord1.getRecordStatus() == 4) {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("您已取消预约请勿重复提交。");
            resultModel.setData(talksRecord);
        } else if (talksRecord1.getRecordStatus() == 3) {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("会谈已结束您无需取消。");
            resultModel.setData(talksRecord);
        } else {
            talksRecord.setRecordStatus(4);
            int row = talksRecordMapper.update(talksRecord);
            resultModel.setCode(Commond.CODE_SUCCESS);
            resultModel.setMessage(MSG_SUCCESS);
            resultModel.setData(row);
        }
        return resultModel;
    }

    @Override
    public ResultModel<PageInfo<TalksRecord>> selectDoctorList(DoctorWebDto doctorWebDto) {
        ResultModel resultModel = new ResultModel();

        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", doctorWebDto.getBeginTime());
        // 排除医生或客户已结束的
        map.put("recordListStatus", 3);
        // 排除客户主动取消预约的
        map.put("endRecordListStatus", 4);
        // 根据科室选择
        map.put("departmentId", doctorWebDto.getDepartmentId());
        //进行中的在前,未开始的按照时间降序
        map.put("sortColumns", "create_time ASC");
        Page p = PageHelper.startPage(doctorWebDto.getPageNum(), doctorWebDto.getPageSize());
        List<TalksRecord> talksRecords = talksRecordMapper.selectList(map);
        //手机号脱敏处理
//        List<TalksRecord> talksRecordRes = new ArrayList<>();
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < talksRecords.size(); i++) {
//            TalksRecord talksRecord = talksRecords.get(i);
//            talksRecord.setTelReal(talksRecord.getTel());
//            talksRecord.setTel(talksRecord.getTel().replaceAll(PHONE_BLUR_REGEX, PHONE_BLUR_REPLACE_REGEX));
//
//            sb.delete(0, sb.length());
//
//            if (i == 0) {
//                sb.append("您目前处于队列中第一位,请进入会谈");
//                talksRecord.setHintMessage(sb.toString());
//            } else if (i == 1) {
//                sb.append("您目前处于第二位,请到排队区等候");
//                talksRecord.setHintMessage(sb.toString());
//            } else {
//                sb.append("当前队列中共").append(talksRecords.size()).append("人,您处于第").append(i + 1).append("位,请耐心等候");
//                talksRecord.setHintMessage(sb.toString());
//
//            }
//            talksRecordRes.add(talksRecord);
//        }
        PageInfo<TalksRecord> pageInfo = new PageInfo<>(doctorWebDto.getPageNum(), doctorWebDto.getPageSize(), p.getTotal(), p.getPages(), talksRecords);
        resultModel.setCode(Commond.CODE_SUCCESS);
        resultModel.setMessage(R_SUCCESS);
        resultModel.setData(pageInfo);
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> getWXOpenid(String jsCode) {
        String url = "https://api.weixin.qq.com/sns/jscode2session";

        Map<String,String> requestUrlParam = new HashMap<String,String>();
        requestUrlParam.put("appid", "wx311db324b43462d2");  //开发者设置中的appId
        requestUrlParam.put("secret", "3aa5450f372c9a5e6b3841a5bd4850aa"); //开发者设置中的appSecret
        requestUrlParam.put("js_code", jsCode); //小程序调用wx.login返回的code
        requestUrlParam.put("grant_type", "authorization_code");    //默认参数
        JSONObject jsonObject = JSON.parseObject(sendPost(url, requestUrlParam));

        ResultModel resultModel = new ResultModel();
        resultModel.setCode(Commond.CODE_SUCCESS);
        resultModel.setMessage(MSG_SUCCESS);
        resultModel.setData(jsonObject);
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> endRecord(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();
        TalksRecord talksRecord1 = talksRecordMapper.selectById((int) (talksRecord.getId()));
        if (talksRecord1.getRecordStatus() == 1) {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("您未开始请稍后再试。");
            resultModel.setData(talksRecord);
        } else if (talksRecord1.getRecordStatus() == 2) {
            talksRecord.setRecordStatus(3);
            int row = talksRecordMapper.update(talksRecord);
            resultModel.setCode(Commond.CODE_SUCCESS);
            resultModel.setMessage(MSG_SUCCESS);
            resultModel.setData(row);
        } else {
            resultModel.setCode(Commond.CODE_FAIL);
            resultModel.setMessage("您未开始请稍后再试。");
            resultModel.setData(talksRecord);
        }
        return resultModel;
    }

    @Override
    public ResultModel<Boolean> doctorEndRecord(TalksRecord talksRecord) {
        ResultModel resultModel = new ResultModel();
        talksRecord.setRecordStatus(3);
        int row = talksRecordMapper.update(talksRecord);
        resultModel.setCode(Commond.CODE_SUCCESS);
        resultModel.setMessage(MSG_SUCCESS);
        resultModel.setData(row);
        return resultModel;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param paramMap 请求参数
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, Map<String, ?> paramMap) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";


        String param = "";
        Iterator<String> it = paramMap.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            param += key + "=" + paramMap.get(key) + "&";
        }
        param = param.substring(0, param.length() - 1);
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
            // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}
